module arm.timer;

import chip;
import arm.misc;
import arm;

private enum bool hasBusPeriph = HasPeriph!("TIM1", "TIM2", "TIM3", "TIM4", "TIM5", "TIM6", "TIM7", "TIM8", "TIM9", "TIM10", "TIM11", "TIM12", "TIM13", "TIM14");

static if(hasBusPeriph):
import core.attribute;
import core.atomic;
import ldc.sanitizers_optionally_linked;

private{
    /// 位标志定义
    enum MaskFlags{
        CR1_CEN = combineMasks!(0),             /// 使能定时器
        CR1_UDIS = combineMasks!(1),            /// 更新禁止
        CR1_URS = combineMasks!(2),             /// 更新请求源
        CR1_OPM = combineMasks!(3),             /// 单次模式
        CR1_DIR = combineMasks!(4),             /// 计数方向
        CR1_CMS = combineMasks!(5,6),           /// 中心对齐模式
        CR1_ARPE = combineMasks!(7),            /// 自动重装载预装载使能
        CR1_CKD = combineMasks!(8,9),           /// 时钟分割
        /// CR1 过滤掩码
        CR1_Filter = CR1_CEN | CR1_UDIS | CR1_URS | CR1_OPM | CR1_DIR | CR1_CMS | CR1_ARPE | CR1_CKD,
        
        CR2_CCDS = combineMasks!(3),            /// 捕获/比较 DMA 选择
        CR2_MMS = combineMasks!(4,5,6),         /// 触发输出
        CR2_TI1S = combineMasks!(7),            /// TI1S 选择
        CR2_Filter = CR2_CCDS | CR2_MMS | CR2_TI1S, /// CR2 过滤掩码

        SMCR_SMS = combineMasks!(0,1,2),        /// 系统时钟模式
        SMCR_TS = combineMasks!(4,5,6),         /// 触发选择
        SMCR_MSM = combineMasks!(7),            /// 主模式选择
        SMCR_ETF = combineMasks!(8,9,10,11),    /// 外部触发滤波
        SMCR_ETPS = combineMasks!(12,13),       /// 外部触发预分频
        SMCR_ECE = combineMasks!(14),           /// 外部触发清除
        SMCR_ETP = combineMasks!(15),           /// 外部触发极性
        SMCR_Filter = SMCR_SMS | SMCR_TS | SMCR_MSM | SMCR_ETF | SMCR_ETPS | SMCR_ECE | SMCR_ETP, /// SMCR 过滤掩码

        DIER_UIE = combineMasks!(0),            /// 更新中断使能
        DIER_CC1IE = combineMasks!(1),          /// 捕获/比较1中断使能
        DIER_CC2IE = combineMasks!(2),          /// 捕获/比较2中断使能
        DIER_CC3IE = combineMasks!(3),          /// 捕获/比较3中断使能
        DIER_CC4IE = combineMasks!(4),          /// 捕获/比较4中断使能
        DIER_TIE = combineMasks!(6),            /// 触发中断使能
        DIER_UDE = combineMasks!(8),            /// 更新DMA请求使能
        DIER_CC1DE = combineMasks!(9),          /// 捕获/比较1DMA请求使能
        DIER_CC2DE = combineMasks!(10),         /// 捕获/比较2DMA请求使能
        DIER_CC3DE = combineMasks!(11),         /// 捕获/比较3DMA请求使能
        DIER_CC4DE = combineMasks!(12),         /// 捕获/比较4DMA请求使能
        DIER_TDE = combineMasks!(14),           /// 触发DMA请求使能
        DIER_Filter = DIER_UIE | DIER_CC1IE | DIER_CC2IE | DIER_CC3IE | DIER_CC4IE | DIER_TIE | DIER_UDE | DIER_CC1DE | DIER_CC2DE | DIER_CC3DE | DIER_CC4DE | DIER_TDE, /// DIER 过滤掩码

        SR_UIF = combineMasks!(0),              /// 更新中断标志
        SR_CC1IF = combineMasks!(1),            /// 捕获/比较1中断标志
        SR_CC2IF = combineMasks!(2),            /// 捕获/比较2中断标志
        SR_CC3IF = combineMasks!(3),            /// 捕获/比较3中断标志
        SR_CC4IF = combineMasks!(4),            /// 捕获/比较4中断标志
        SR_TIF = combineMasks!(6),              /// 触发中断标志
        SR_CC1OF = combineMasks!(9),            /// 捕获/比较1重载标志
        SR_CC2OF = combineMasks!(10),           /// 捕获/比较2重载标志
        SR_CC3OF = combineMasks!(11),           /// 捕获/比较3重载标志
        SR_CC4OF = combineMasks!(12),           /// 捕获/比较4重载标志
        SR_Filter = SR_UIF | SR_CC1IF | SR_CC2IF | SR_CC3IF | SR_CC4IF | SR_TIF | SR_CC1OF | SR_CC2OF | SR_CC3OF | SR_CC4OF, /// SR 过滤掩码

        EGR_UG = combineMasks!(0),              /// 更新事件
        EGR_CC1G = combineMasks!(1),            /// 捕获/比较1事件
        EGR_CC2G = combineMasks!(2),            /// 捕获/比较2事件
        EGR_CC3G = combineMasks!(3),            /// 捕获/比较3事件
        EGR_CC4G = combineMasks!(4),            /// 捕获/比较4事件
        EGR_TG = combineMasks!(6),              /// 触发事件
        EGR_Filter = EGR_UG | EGR_CC1G | EGR_CC2G | EGR_CC3G | EGR_CC4G | EGR_TG, /// EGR 过滤掩码

        CCMR1_CC1S = combineMasks!(0,1),        /// 捕获/比较1选择
        CCMR1_OC1FE = combineMasks!(2),         /// 捕获/比较1快速使能
        CCMR1_OC1PE = combineMasks!(3),         /// 捕获/比较1预装载使能
        CCMR1_IC1PSC = CCMR1_OC1FE | CCMR1_OC1PE,      /// 输入捕获1预分频

        CCMR1_OC1M = combineMasks!(4,5,6),      /// 捕获/比较1模式
        CCMR1_OC1CE = combineMasks!(7),         /// 捕获/比较1清除使能
        CCMR1_IC1F = CCMR1_OC1M | CCMR1_OC1CE,  /// 输入捕获1滤波器
        CCMR1_CC2S = combineMasks!(8,9),        /// 捕获/比较2选择
        CCMR1_OC2FE = combineMasks!(10),        /// 捕获/比较2快速使能
        CCMR1_OC2PE = combineMasks!(11),        /// 捕获/比较2预装载使能
        CCMR1_IC2PSC = CCMR1_OC2FE | CCMR1_OC2PE,      /// 输入捕获2预分频
        CCMR1_OC2M = combineMasks!(12,13,14),  /// 捕获/比较2模式
        CCMR1_OC2CE = combineMasks!(15),        /// 捕获/比较2清除使能
        CCMR1_IC2F = CCMR1_OC2M | CCMR1_OC2CE,  /// 输入捕获2滤波器
        CCMR1_Filter = CCMR1_CC1S | CCMR1_OC1FE | CCMR1_OC1PE | CCMR1_OC1M | CCMR1_OC1CE | CCMR1_CC2S | CCMR1_OC2FE | CCMR1_OC2PE | CCMR1_OC2M | CCMR1_OC2CE, /// CCMR1 过滤掩码

        CCMR2_CC3S = combineMasks!(0,1),        /// 捕获/比较3选择
        CCMR2_OC3FE = combineMasks!(2),         /// 捕获/比较3快速使能
        CCMR2_OC3PE = combineMasks!(3),         /// 捕获/比较3预装载使能
        CCMR2_IC3PSC = CCMR2_OC3FE | CCMR2_OC3PE,      /// 输入捕获3预分频
        CCMR2_OC3M = combineMasks!(4,5,6),      /// 捕获/比较3模式
        CCMR2_OC3CE = combineMasks!(7),         /// 捕获/比较3清除使能
        CCMR2_IC3F = CCMR2_OC3M | CCMR2_OC3CE,  /// 输入捕获3滤波器
        CCMR2_CC4S = combineMasks!(8,9),        /// 捕获/比较4选择
        CCMR2_OC4FE = combineMasks!(10),        /// 捕获/比较4快速使能
        CCMR2_OC4PE = combineMasks!(11),        /// 捕获/比较4预装载使能
        CCMR2_IC4PSC = CCMR2_OC4FE | CCMR2_OC4PE,      /// 输入捕获4预分频
        CCMR2_OC4M = combineMasks!(12,13,14),  /// 捕获/比较4模式
        CCMR2_OC4CE = combineMasks!(15),        /// 捕获/比较4清除使能
        CCMR2_IC4F = CCMR2_OC4M | CCMR2_OC4CE,  /// 输入捕获4滤波器
        CCMR2_Filter = CCMR2_CC3S | CCMR2_OC3FE | CCMR2_OC3PE | CCMR2_OC3M | CCMR2_OC3CE | CCMR2_CC4S | CCMR2_OC4FE | CCMR2_OC4PE | CCMR2_OC4M | CCMR2_OC4CE, /// CCMR2 过滤掩码

        CCER_CC1E = combineMasks!(0),           /// 捕获/比较1输出使能
        CCER_CC1P = combineMasks!(1),           /// 捕获/比较1输出极性
        CCER_CC1NP = combineMasks!(3),          /// 捕获/比较1互补输出极性
        CCER_CC2E = combineMasks!(4),           /// 捕获/比较2输出使能
        CCER_CC2P = combineMasks!(5),           /// 捕获/比较2输出极性
        CCER_CC2NP = combineMasks!(7),          /// 捕获/比较2互补输出极性
        CCER_CC3E = combineMasks!(8),           /// 捕获/比较3输出使能
        CCER_CC3P = combineMasks!(9),           /// 捕获/比较3输出极性
        CCER_CC3NP = combineMasks!(11),         /// 捕获/比较3互补输出极性
        CCER_CC4E = combineMasks!(12),          /// 捕获/比较4输出使能
        CCER_CC4P = combineMasks!(13),          /// 捕获/比较4输出极性
        CCER_CC4NP = combineMasks!(15),         /// 捕获/比较4互补输出极性
        CCER_Filter = CCER_CC1E | CCER_CC1P | CCER_CC1NP | CCER_CC2E | CCER_CC2P | CCER_CC2NP | CCER_CC3E | CCER_CC3P | CCER_CC3NP | CCER_CC4E | CCER_CC4P | CCER_CC4NP, /// CCER 过滤掩码

        DCR_DBA = combineMasks!(0,1,2,3,4),     /// DMA 基地址
        DCR_DBL = combineMasks!(8,9,10,11,12),  /// DMA缓冲区长度
        DCR_Filter = DCR_DBA | DCR_DBL,         /// DCR 过滤掩码

        DMAR_DMAB = ushort.max,                 /// DMA寄存器地址
    }    

    /**
    * 定时器通用结构体
    */
    struct TIM_Struct
    {
        uint CR1;           /// 控制寄存器1 偏移地址 $(D 0x00)
        uint CR2;           /// 控制寄存器2 偏移地址 $(D 0x04)
        uint SMCR;          /// 外部触发寄存器 偏移地址 $(D 0x08)
        uint DIER;          /// 中断使能寄存器 偏移地址 $(D 0x0C)
        uint SR;            /// 状态寄存器 偏移地址 $(D 0x10)
        uint EGR;           /// 事件生成寄存器 偏移地址 $(D 0x14)
        uint CCMR1;         /// 捕获/比较模式寄存器1 偏移地址 $(D 0x18)
        uint CCMR2;         /// 捕获/比较模式寄存器2 偏移地址 $(D 0x1C)
        uint CCER;          /// 捕获/比较使能寄存器 偏移地址 $(D 0x20)
        uint CNT;           /// 计数器 偏移地址 $(D 0x24)
        uint PSC;           /// 预分频器 偏移地址 $(D 0x28)
        uint ARR;           /// 自动重装载寄存器 偏移地址 $(D 0x2C)
        uint RCR;           /// 重复计数寄存器 偏移地址 $(D 0x30)
        uint CCR1;          /// 捕获/比较寄存器1 偏移地址 $(D 0x34)
        uint CCR2;          /// 捕获/比较寄存器2 偏移地址 $(D 0x38)
        uint CCR3;          /// 捕获/比较寄存器3 偏移地址 $(D 0x3C)
        uint CCR4;          /// 捕获/比较寄存器4 偏移地址 $(D 0x40)
        uint BDTR;          /// 重复计数寄存器 偏移地址 $(D 0x44)
        uint DCR;           /// 重复计数寄存器 偏移地址 $(D 0x48)
        uint DMAR;          /// 重复计数寄存器 偏移地址 $(D 0x4C)
        uint OR;            /// 重复计数寄存器 偏移地址 $(D 0x50)
    }
    /**
    * 通道标记
    */
    enum Channel : ubyte
    {
        Channel_1 = 0,      /// 通道1
        Channel_2,          /// 通道2
        Channel_3,          /// 通道3
        Channel_4,          /// 通道4
    }
}




version(NONE):


/**
* 定时器11模板
*Params: irq = 是否产生中断回调
*/
abstract class Timer11(bool irq)
{
        static if(irq == true)
    {
        
        //mixin MakerIRQHandler!(WWDG_IRQHandler,m_Callhandler);
    }
    __gshared CallHandler m_Callhandler;
    /// 设置中断函数
    static if(irq == true)
    static void setIRQHandler(CallHandler handler)
    {
        m_Callhandler = handler;
    }

    //pragma(mangle,"WWDG_IRQHandler") 
    //@naked @weak extern(C) void c_WWDG_IRQHandler() {if(m_Callhandler !is null) m_Callhandler();}

    void test1()
    {
    }


}

/**
* 通用定时器模板
* Params: Peripheral = 定时器模块
* todo: isFinalClass 判定出错 由 isAbstractClass 代替
*/
final abstract class D_Timer(alias Peripheral)  if(__traits(isAbstractClass, Peripheral))
{
    static if((Peripheral.stringof == "TIM2") || (Peripheral.stringof == "TIM5")){
        alias valType = uint;
    }else{
        alias valType = ushort;
    }

    enum{
        TIM_CNT = valType.max,          /// 计数器值
        TIM_PSC = valType.max,          /// 预分频器值
        TIM_ARR = valType.max,          /// 自动重装载寄存器值
        TIM_CCR1 = valType.max,         /// 捕获/比较寄存器1值
        TIM_CCR2 = valType.max,         /// 捕获/比较寄存器2值
        TIM_CCR3 = valType.max,         /// 捕获/比较寄存器3值
        TIM_CCR4 = valType.max,         /// 捕获/比较寄存器4值
    }

    enum shared(TIM_Struct*) pTim = RegMap!(Peripheral.PeripheralAddress, TIM_Struct);
    /// 使能定时器
    pragma(inline,_inline)
    static void enable()
    {
        //Peripheral.CR1 |= 1;
        //atomicOp!"+="(Peripheral.CR1, 1);
        TIM1.CR1.CEN.val(true);
    }
    /// 禁用定时器
    pragma(inline,_inline)
    static void Disable()
    {
        TIM1.CR1.CEN.val(false);
    }
    /// 通用: 配置
    static void Config()
    {

    }
    //--------------------------------------------------------------------------
    /**
    * 中断服务
    */
}
//extern(C) 

//TIM1.PeripheralAddress
/// 

//alias Timer1 = D_Timer!(TIM1);

